package com.example.crawlerjava.service.crawler.core;

import cn.hutool.core.util.ObjectUtil;
import com.example.crawlerjava.config.Clm8Config;
import com.example.crawlerjava.config.CrawlerConfig;
import com.example.crawlerjava.service.crawler.CrawlerStrategy;
import com.example.crawlerjava.entity.Clm8Entity;
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.ElementState;
import com.microsoft.playwright.options.LoadState;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service("clm8Crawler")
public class Clm8CrawlerImpl implements CrawlerStrategy<Clm8Entity> {

    @Resource
    private CrawlerConfig crawlerConfig;
    @Resource
    private Clm8Config clm8Config;

    @Override
    public List<Clm8Entity> search(String searchKey) {
        if (ObjectUtil.isEmpty(searchKey)) {
            return Collections.emptyList();
        }
        log.info("开始搜索:{}", searchKey);
        List<Clm8Entity> clm8Entities = new ArrayList<>();

        try (Playwright playwright = Playwright.create()) {
            String baseUrl = clm8Config.getBaseUrl();
            BrowserType chromium = playwright.chromium();
            Path userDataDir = Paths.get(clm8Config.getSaveFile());
            BrowserType.LaunchPersistentContextOptions options = new BrowserType.LaunchPersistentContextOptions();
            //这里代表是否要可视化，false代表可视化，true代表非可视化
            if (crawlerConfig.getOpenView()) {
                options.setHeadless(false);
                options.setViewportSize(1920, 1080);
            } else {
                options.setHeadless(true);
            }

            options.setAcceptDownloads(true);

            BrowserContext browserContext = chromium.launchPersistentContext(userDataDir, options);
            browserContext.setDefaultTimeout(300000);


            URL url = this.getClass().getResource("/" + "stealth.min.js");
            Path filePath = Paths.get(url.toURI());
            browserContext.addInitScript(filePath);
            Page page = browserContext.newPage();

            page.navigate(baseUrl);
            try {
                page.waitForSelector("//div[@class=\"attribution\"]/a", new Page.WaitForSelectorOptions().setTimeout(2000));
                page.click("//div[@class=\"attribution\"]/a");
            } catch (Exception e) {
                log.info("没有找到按钮,跳过");
            }
            page.waitForLoadState(LoadState.NETWORKIDLE);
            try {
                page.waitForSelector("//div[@class=\"layui-layer-btn layui-layer-btn-\"]/a[starts-with(@class, \"layui-layer\")]"
                        , new Page.WaitForSelectorOptions().setTimeout(2000));
                page.click("//div[@class=\"layui-layer-btn layui-layer-btn-\"]/a[starts-with(@class, \"layui-layer\")]");
            } catch (Exception e) {
                log.info("没有找到按钮,跳过");
            }

            // 定位输入框
            Locator inputLocator = page.locator("input#SearchForm_keyword");
            // 清除输入框内容（如果有的话）
            inputLocator.fill(searchKey);
            page.waitForSelector("#SearchForm_submit_btn_wrapper", new Page.WaitForSelectorOptions().setTimeout(5000));
            page.click("#SearchForm_submit_btn_wrapper");
            //等待加载完毕
            page.waitForLoadState(LoadState.NETWORKIDLE);

            // 获取所有的a标签
            List<ElementHandle> links = page.querySelectorAll(".SearchListTitle_list_title a");
            // 遍历并每个链接
            for (ElementHandle link : links) {
                // 点击前可以等待元素可见或可交互
                link.waitForElementState(ElementState.VISIBLE);
                String href = link.getAttribute("href");
                String clickUrl = baseUrl + href;
                Page childPage = browserContext.newPage();
                childPage.navigate(clickUrl);
                // 等待加载完毕
                childPage.waitForLoadState(LoadState.NETWORKIDLE);
                // 获取a标签的href属性
                String magnetLink = childPage.getAttribute(".Information_magnet", "href");
                // 获取<h1>标签的文本内容
                String title = childPage.textContent("h1.Information_title");

                log.info("获取到一条磁力链接:{}", magnetLink);

                Clm8Entity clm8Entity = new Clm8Entity();
                clm8Entity.setSourceUrl(magnetLink);
                clm8Entity.setSourceName(title);

                clm8Entities.add(clm8Entity);
                childPage.close();
            }
            log.info("{} 搜索完毕退出程序~", searchKey);
        } catch (Exception e) {
            log.error("搜索异常:", e);
        }

        return clm8Entities;
    }

    @Override
    public Clm8Entity getDetail(String detailUrl) {
        return null;
    }

    @Override
    public String getDownloadUrl(String downloadUrl) {
        return null;
    }
}
